package com.alameda.common.utils;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import io.swagger.annotations.ApiModelProperty;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.List;

/**
 * excle工具类
 *
 * @author Lv
 * @date 2024/3/31
 */
public class ExcelUtils {
    /**
     * 导出excel表格
     *
     * @param list     内容信息集合
     * @param tClass   对象类型字节码
     * @param fileName 文件名称
     * @param <T>      泛型
     */
    public static <T> void export(List<T> list, Class<T> tClass, String fileName) {
        export(list, tClass, fileName, HttpUtils.getHttpServletResponse());
    }

    /**
     * 导出excel表格
     *
     * @param list                内容信息集合
     * @param tClass              对象类型字节码
     * @param fileName            文件名称
     * @param httpServletResponse http 响应对象
     * @param <T>                 泛型
     */
    private static <T> void export(List<T> list, Class<T> tClass, String fileName, HttpServletResponse httpServletResponse) {
        // 通过工具类创建writer，默认创建xls格式
        ExcelWriter writer = ExcelUtil.getWriter(true);
        Field[] fields = tClass.getDeclaredFields();
        int column = 0;
        for (Field field : fields) {
            ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
            if (PubUtils.isNotNull(apiModelProperty)) {
                writer.addHeaderAlias(field.getName(), apiModelProperty.value());
                column += 1;
            }
        }

        // 合并单元格后的标题行，使用默认标题样式
        writer.merge(column - 1, fileName);

        writer.write(list, true);

        // 设置所有列为自动宽度，不考虑合并单元格
        setSizeColumn(writer.getSheet(), 2);
        httpServletResponse.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        ServletOutputStream out = null;
        try {
            String exportFileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + exportFileName);
            out = httpServletResponse.getOutputStream();
            writer.flush(out, true);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭writer，释放内存
            writer.close();
        }
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    /**
     * 自适应宽度(中文支持)
     *
     * @param sheet sheet
     * @param size  因为for循环从0开始，size值为 列数-1
     */
    private static void setSizeColumn(Sheet sheet, int size) {
        for (int columnNum = 0; columnNum <= size; columnNum++) {
            int columnWidth = sheet.getColumnWidth(columnNum) / 256;
            for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
                Row currentRow;
                //当前行未被使用过
                if (sheet.getRow(rowNum) == null) {
                    currentRow = sheet.createRow(rowNum);
                } else {
                    currentRow = sheet.getRow(rowNum);
                }

                if (currentRow.getCell(columnNum) != null) {
                    Cell currentCell = currentRow.getCell(columnNum);
                    if (currentCell.getCellType() == CellType.STRING) {
                        int length = currentCell.getStringCellValue().getBytes().length;
                        if (columnWidth < length) {
                            columnWidth = length;
                        }
                    }
                }
            }
            sheet.setColumnWidth(columnNum, columnWidth * 255);
        }
    }
}
